import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_note/note/const.dart';
import 'package:flutter_note/note/utils.dart';
import 'bean.dart';

class UserManager {
  User _user;
  static UserManager _userManager;

  static UserManager getInstance() {
    if (_userManager == null) {
      _userManager = UserManager();
    }
    return _userManager;
  }

  User getUser() => _user;

  save(String data) {
    if (EmptyUtils.isNotEmpty(data)) {
      _user = User.fromJson(json.decode(data));
      if (EmptyUtils.isNotEmpty(_user.token)) {
        SPUtils.setString(Const.SP_TOKEN, _user.token);
      }
    }
  }

  Future<Reply> userModify(name, about, head) async {
    //登录请求
    var map = {
      'uid': _user.uid.toString(),
      'name': name,
      'about': about,
      'head': head,
      'token': _user.token
    };
    Reply reply = await HttpUtils.post(map, Const.API_UPDATE_USER);
    if (reply.code == Const.SUCCESS) {
      save(reply.data);
    }
    return reply;
  }

  //注册请求
  Future<Reply> register(String name, String username, String password) async {
    var map = {"name": name, "username": username, "password": password};
    Reply reply = await HttpUtils.post(map, Const.API_REGISTER);
    return reply;
  }

  //修改密码请求
  Future<Reply> passwordModify(String password, String newPassword) async {
    var map = {
      'uid': _user.uid.toString(),
      "password": password,
      "newPassword": newPassword,
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_UPDATE_ACCOUNT);
    return reply;
  }

  //账户登录请求
  Future<Reply> login(String username, String password) async {
    password = EncryptUtils.md5e(password);
    var map = {"username": username, "password": password};
    Reply reply = await HttpUtils.post(map, Const.API_LOGIN);
    if (reply.code == Const.SUCCESS) {
      save(reply.data);
      SPUtils.setString(Const.SP_USERNAME, username);
    }
    return reply;
  }

  //token登录请求
  Future<Reply> tokenLogin(String token) async {
    var map = {"token": token};
    Reply reply = await HttpUtils.post(map, Const.API_LOGIN);
    if (reply.code == Const.SUCCESS) {
      save(reply.data);
    }
    return reply;
  }

  void logout() {
    SPUtils.setString(Const.SP_TOKEN, "");
    UserManager.getInstance()._user = null;
    NoteManager.getInstance()._noteList = null;
    BookManager.getInstance()._bookList = null;
    BookNoteManager.getInstance()._noteList = null;
    CommentManager.getInstance()._commentList = null;
  }
}

class NoteManager {
  ReplyNote _currentNote = ReplyNote();
  List<ReplyNote> _noteList = [];
  static NoteManager _noteManager;

  static NoteManager getInstance() {
    if (_noteManager == null) {
      _noteManager = NoteManager();
    }
    return _noteManager;
  }

  ReplyNote getCurrentNote() => _currentNote;

  setCurrentNote(currentNote) {
    this._currentNote = currentNote;
  }

  List<ReplyNote> getNoteList() => _noteList;

  //加载数据
  Future<Reply> loadData() async {
    var map = {
      "bid": "0",
      "time": DateTime.now().millisecondsSinceEpoch.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        _noteList = replyNoteList.data;
      }
    }
    return reply;
  }

  //加载更多数据
  Future<Reply> loadMoreData() async {
    var map = {
      "bid": "0",
      "time": _noteList.last.nTime.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        print("replyNoteList.size = "+ replyNoteList.data.length.toString());
        _noteList.addAll(replyNoteList.data);
        if (replyNoteList.data.length < Const.PAGE_SIZE) {
          reply.code = Const.FAIL_NONE;
        }
      }
    }
    return reply;
  }

  //发送创建笔记本
  Future<Reply> createNote(int bid, String content, String pic) async {
    var map = {
      "bid": bid.toString(),
      "uid": UserManager.getInstance().getUser().uid.toString(),
      "content": content,
      "token": UserManager.getInstance().getUser().token
    };
    if (EmptyUtils.isNotEmpty(pic)) {
      map.addAll({"pic": pic});
    }
    Reply reply = await HttpUtils.post(map, Const.API_ADD_NOTE);
    return reply;
  }
}

class MarkManager {
  List<ReplyNote> _markList = [];
  static MarkManager _markManager;

  static MarkManager getInstance() {
    if (_markManager == null) {
      _markManager = MarkManager();
    }
    return _markManager;
  }

  List<ReplyNote> getMarkList() => _markList;

  //加载数据
  Future<Reply> loadData() async {
    var map = {
      "mid": UserManager.getInstance().getUser().uid.toString(),
      "time": DateTime.now().millisecondsSinceEpoch.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_MARK_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        _markList = replyNoteList.data;
      }
    }
    return reply;
  }

  //加载更多数据
  Future<Reply> loadMoreData() async {
    var map = {
      "mid": UserManager.getInstance().getUser().uid.toString(),
      "time": _markList.last.nTime.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_MARK_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        _markList.addAll(replyNoteList.data);
        if (replyNoteList.data.length < Const.PAGE_SIZE) {
          reply.code = Const.FAIL_NONE;
        }
      }
    }
    return reply;
  }

  //是否关注日记
  Future<Reply> getMark(int nid) async {
    var map = {
      "mid": UserManager.getInstance().getUser().uid.toString(),
      "nid": nid.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_MARK);
    return reply;
  }

  //添加关注
  Future<Reply> addMark(int nid) async {
    var map = {
      "mid": UserManager.getInstance().getUser().uid.toString(),
      "nid": nid.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_ADD_MARK);
    return reply;
  }

  //取消关注
  Future<Reply> deleteMark(int nid) async {
    var map = {
      "mid": UserManager.getInstance().getUser().uid.toString(),
      "nid": nid.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_DELETE_MARK);
    return reply;
  }
}

class BookManager {
  List<Book> _bookList = [];
  static BookManager _bookManager;

  static BookManager getInstance() {
    if (_bookManager == null) {
      _bookManager = BookManager();
    }
    return _bookManager;
  }

  List<Book> getBookList() => _bookList;

  save(String data) {
    if (EmptyUtils.isNotEmpty(data)) {
      var bookList = BookList.fromJson(data);
      if (bookList != null) {
        _bookList = bookList.data;
      }
    }
  }

  //加载数据
  loadData() async {
    var map = {
      "uid": UserManager.getInstance().getUser().uid.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_BOOK_LIST);
    save(reply.data);
  }

  //发送创建笔记本
  Future<Reply> createBook(String title, String msg, String pic) async {
    var map = {
      "uid": UserManager.getInstance().getUser().uid.toString(),
      "title": title,
      "token": UserManager.getInstance().getUser().token
    };
    if (EmptyUtils.isNotEmpty(msg)) {
      map.addAll({"msg": msg});
    }
    if (EmptyUtils.isNotEmpty(pic)) {
      map.addAll({"pic": pic});
    }
    Reply reply = await HttpUtils.post(map, Const.API_ADD_BOOK);
    return reply;
  }
}

class BookNoteManager {
  List<ReplyNote> _noteList = [];
  Book _currentBook;
  static BookNoteManager _bookNoteManager;

  static BookNoteManager getInstance() {
    if (_bookNoteManager == null) {
      _bookNoteManager = BookNoteManager();
    }
    return _bookNoteManager;
  }

  Book getCurrentBook() => _currentBook;

  setCurrentBook(currentBook) {
    this._currentBook = currentBook;
  }

  List<ReplyNote> getNoteList() => _noteList;

  save(String data) {
    if (EmptyUtils.isNotEmpty(data)) {
      var replyNoteList = ReplyNoteList.fromJson(data);
      if (replyNoteList != null) {
        _noteList = replyNoteList.data;
      }
    }
  }

  //加载数据
  Future<Reply> loadData() async {
    var map = {
      "bid": _currentBook.bid.toString(),
      "time": DateTime.now().millisecondsSinceEpoch.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        _noteList = replyNoteList.data;
      }
    }
    return reply;
  }

  //加载更多数据
  Future<Reply> loadMoreData() async {
    var map = {
      "bid": _currentBook.bid.toString(),
      "time": _noteList.last.nTime.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_NOTE_LIST);
    if (EmptyUtils.isNotEmpty(reply.data)) {
      var replyNoteList = ReplyNoteList.fromJson(reply.data);
      if (replyNoteList != null) {
        _noteList.addAll(replyNoteList.data);
      }
    }
    return reply;
  }
}

class CommentManager {
  ReplyComment _currentComment;
  List<ReplyComment> _commentList = [];
  static CommentManager _commentManager;

  static CommentManager getInstance() {
    if (_commentManager == null) {
      _commentManager = CommentManager();
    }
    return _commentManager;
  }

  ReplyComment getCurrentComment() => _currentComment;

  setCurrentComment(currentComment) {
    this._currentComment = currentComment;
  }

  List<ReplyComment> getCommentList() => _commentList;

  save(String data) {
    if (EmptyUtils.isNotEmpty(data)) {
      var replyCommentList = ReplyCommentList.fromJson(data);
      if (replyCommentList != null) {
        _commentList = replyCommentList.data;
      }
    }
  }

  //加载数据
  loadData(int nid) async {
    var map = {
      "nid": nid.toString(),
      "time": DateTime.now().millisecondsSinceEpoch.toString(),
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_GET_COMMENT_LIST);
    save(reply.data);
  }

  //发送评论
  Future<Reply> sendComment(int nid, String msg) async {
    var map = {
      "uid": UserManager.getInstance().getUser().uid.toString(),
      "nid": nid.toString(),
      "msg": msg,
      "token": UserManager.getInstance().getUser().token
    };
    Reply reply = await HttpUtils.post(map, Const.API_ADD_COMMENT);
    if (reply.code == Const.SUCCESS) {
      ReplyComment replyComment =
          ReplyComment.fromJson(json.decode(reply.data));
      var user = UserManager.getInstance().getUser();
      replyComment.user = ReplyUser(user.uid, user.name, user.head);
      print(replyComment.toString());
      _commentList.add(replyComment);
      _commentList.sort(comparator);
    }
    return reply;
  }

  int comparator(ReplyComment a, ReplyComment b) {
    return b.cTime - a.cTime;
  }
}

class UploadFileManager {
  static UploadFileManager _uploadFileManager;

  static UploadFileManager getInstance() {
    if (_uploadFileManager == null) {
      _uploadFileManager = UploadFileManager();
    }
    return _uploadFileManager;
  }

  Future<Reply> uploadFile(File file) async {
    String headName = file.path.substring(file.path.lastIndexOf('/') + 1);
    var map = {Const.UPLOAD_FILE: UploadFileInfo(file, headName)};
    Reply reply = await HttpUtils.post(map, Const.API_UPLOAD);
    return reply;
  }
}
